package org.smart4j.framework.helper;


import cn.wenxin_zhang.smart4j.plus.annotation.Mapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.smart4j.framework.annotation.Controller;
import org.smart4j.framework.annotation.Service;
import org.smart4j.framework.utils.ClassUtil;

import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.Set;

/**
 * Created by Wenxin on 2017/2/25.
 */
public class ClassHelper {
    private static final Logger LOGGER = LoggerFactory.getLogger(ClassHelper.class);
    public static final Set<Class<?>> CLASS_SET;

    static {
        String basePackage = ConfigHelper.getAppBasePackage();
        CLASS_SET = ClassUtil.getClassSet(basePackage);
    }

    /**
     * 获取包名下所有类
     *
     * @return
     */
    public static Set<Class<?>> getClassSet() {
        return CLASS_SET;
    }

    public static Set<Class<?>> getMapperClassSet() {
        Set<Class<?>> mapperClassSet = new HashSet<>();
        for (Class<?> cls : CLASS_SET) {
            if (cls.isAnnotationPresent(Mapper.class)) {
//                不是接口的mapper不代理
                if (cls.isInterface()) {
                    mapperClassSet.add(cls);
                    LOGGER.debug("load mapper:{}", cls.getName());
                }
            }
        }
        return mapperClassSet;
    }

    public static Set<Class<?>> getServiceClassSet() {

        Set<Class<?>> classSet = new HashSet<>();
        for (Class<?> cls : CLASS_SET) {
            if (cls.isAnnotationPresent(Service.class))
                classSet.add(cls);
        }
        return classSet;
    }

    public static Set<Class<?>> getControllerClassSet() {

        Set<Class<?>> classSet = new HashSet<>();
        for (Class<?> cls : CLASS_SET) {
            if (cls.isAnnotationPresent(Controller.class))
                classSet.add(cls);
        }
        return classSet;
    }

    //    此次只获取可以实例化的类
    public static Set<Class<?>> getBeanClassSet() {

        Set<Class<?>> classSet = new HashSet<>();

        classSet.addAll(getServiceClassSet());
        classSet.addAll(getControllerClassSet());
        return classSet;
    }

    public static Set<Class<?>> getClassBySuper(Class<?> superClass) {

        Set<Class<?>> classSet = new HashSet<>();
        for (Class<?> cls : CLASS_SET) {
            if (superClass.isAssignableFrom(cls) && !superClass.equals(cls)) {
                classSet.add(cls);
            }
        }
        return classSet;
    }

    public static Set<Class<?>> getClassByAnnotation(Class<? extends Annotation> annotation) {

        Set<Class<?>> classSet = new HashSet<>();
        for (Class<?> cls : CLASS_SET) {
            if (cls.isAnnotationPresent(annotation)) {
                classSet.add(cls);
            }
        }
        return classSet;
    }

    public static boolean loadClass(String className) {
        Class<?> aClass = ClassUtil.loadClass(className);
        return CLASS_SET.add(aClass);
    }

}
